<?php
/**
 * 考勤管理类
 * 提供打卡、考勤记录管理、统计等功能
 */

class Attendance {
    private $db;
    
    public function __construct() {
        $this->db = getDB();
    }
    
    /**
     * 上班打卡
     */
    public function clockIn($userId) {
        $today = date('Y-m-d');
        $currentTime = date('H:i:s');
        
        // 检查今天是否已经打卡
        $existing = $this->getTodayRecord($userId);
        
        // 判断是上午打卡还是下午打卡
        $isMorning = $this->isMorningTime($currentTime);
        
        if ($isMorning) {
            // 上午打卡
            if ($existing && $existing['morning_clock_in']) {
                return ['success' => false, 'message' => '今天上午已经打过上班卡'];
            }
            
            $status = $this->calculateClockInStatus($currentTime);
            
            if ($existing) {
                // 更新现有记录
                $sql = "UPDATE attendance_records SET morning_clock_in = ?, status = ? WHERE id = ?";
                $this->db->execute($sql, [$currentTime, $status, $existing['id']]);
            } else {
                // 创建新记录
                $sql = "INSERT INTO attendance_records (user_id, record_date, morning_clock_in, status) VALUES (?, ?, ?, ?)";
                $this->db->execute($sql, [$userId, $today, $currentTime, $status]);
            }
            
            return ['success' => true, 'message' => '上午上班打卡成功', 'time' => $currentTime, 'status' => $status];
        } else {
            // 下午打卡
            if ($existing && $existing['afternoon_clock_in']) {
                return ['success' => false, 'message' => '今天下午已经打过上班卡'];
            }
            
            $status = 'normal'; // 下午打卡默认正常
            
            if ($existing) {
                // 更新现有记录
                $sql = "UPDATE attendance_records SET afternoon_clock_in = ? WHERE id = ?";
                $this->db->execute($sql, [$currentTime, $existing['id']]);
            } else {
                // 创建新记录
                $sql = "INSERT INTO attendance_records (user_id, record_date, afternoon_clock_in, status) VALUES (?, ?, ?, ?)";
                $this->db->execute($sql, [$userId, $today, $currentTime, $status]);
            }
            
            return ['success' => true, 'message' => '下午上班打卡成功', 'time' => $currentTime, 'status' => $status];
        }
    }
    
    /**
     * 下班打卡
     */
    public function clockOut($userId) {
        $today = date('Y-m-d');
        $currentTime = date('H:i:s');
        
        // 获取今天的考勤记录
        $record = $this->getTodayRecord($userId);
        
        // 判断是上午下班还是下午下班
        $isMorning = $this->isMorningTime($currentTime);
        
        if ($isMorning) {
            // 上午下班
            if (!$record || !$record['morning_clock_in']) {
                return ['success' => false, 'message' => '请先进行上午上班打卡'];
            }
            
            if ($record['morning_clock_out']) {
                return ['success' => false, 'message' => '今天上午已经打过下班卡'];
            }
            
            $sql = "UPDATE attendance_records SET morning_clock_out = ? WHERE id = ?";
            $this->db->execute($sql, [$currentTime, $record['id']]);
            
            return ['success' => true, 'message' => '上午下班打卡成功', 'time' => $currentTime];
        } else {
            // 下午下班
            if (!$record || !$record['afternoon_clock_in']) {
                return ['success' => false, 'message' => '请先进行下午上班打卡'];
            }
            
            if ($record['afternoon_clock_out']) {
                return ['success' => false, 'message' => '今天下午已经打过下班卡'];
            }
            
            // 计算总工时
            $totalHours = $this->calculateTotalWorkHours($record);
            
            // 计算最终状态
            $finalStatus = $this->calculateFinalStatus($record['status'], $currentTime);
            
            $sql = "UPDATE attendance_records SET afternoon_clock_out = ?, total_work_hours = ?, status = ? WHERE id = ?";
            $this->db->execute($sql, [$currentTime, $totalHours, $finalStatus, $record['id']]);
            
            return ['success' => true, 'message' => '下午下班打卡成功', 'time' => $currentTime, 'hours' => $totalHours];
        }
    }
    
    /**
     * 获取今天的考勤记录
     */
    public function getTodayRecord($userId) {
        $today = date('Y-m-d');
        $sql = "SELECT * FROM attendance_records WHERE user_id = ? AND record_date = ?";
        return $this->db->querySingle($sql, [$userId, $today]);
    }
    
    /**
     * 判断是否是上午时间
     */
    private function isMorningTime($time) {
        $hour = date('H', strtotime($time));
        return $hour < 12; // 12点前为上午
    }
    
    /**
     * 计算总工时（上午+下午）
     */
    private function calculateTotalWorkHours($record) {
        $totalHours = 0;
        
        // 计算上午工时
        if ($record['morning_clock_in'] && $record['morning_clock_out']) {
            $morningHours = $this->calculateWorkHours($record['morning_clock_in'], $record['morning_clock_out']);
            $totalHours += $morningHours;
        }
        
        // 计算下午工时
        if ($record['afternoon_clock_in'] && $record['afternoon_clock_out']) {
            $afternoonHours = $this->calculateWorkHours($record['afternoon_clock_in'], $record['afternoon_clock_out']);
            $totalHours += $afternoonHours;
        }
        
        return round($totalHours, 2);
    }
    
    /**
     * 计算工作时长
     */
    public function calculateWorkHours($clockIn, $clockOut) {
        $start = strtotime($clockIn);
        $end = strtotime($clockOut);
        
        // 减去午休时间 (12:00-14:00)
        $lunchStart = strtotime('12:00:00');
        $lunchEnd = strtotime('14:00:00');
        
        $totalSeconds = $end - $start;
        
        // 如果打卡时间跨越午休时间，减去午休时长
        if ($start < $lunchEnd && $end > $lunchStart) {
            $lunchOverlap = min($end, $lunchEnd) - max($start, $lunchStart);
            if ($lunchOverlap > 0) {
                $totalSeconds -= $lunchOverlap;
            }
        }
        
        $hours = $totalSeconds / 3600;
        return round($hours, 2);
    }
    
    /**
     * 计算上班打卡状态
     */
    private function calculateClockInStatus($clockInTime) {
        $workStartTime = $this->getConfig('work_start_time', '08:30:00');
        $lateThreshold = $this->getConfig('late_threshold', 15);
        
        $clockInTimestamp = strtotime($clockInTime);
        $workStartTimestamp = strtotime($workStartTime);
        $lateThresholdSeconds = $lateThreshold * 60;
        
        if ($clockInTimestamp > ($workStartTimestamp + $lateThresholdSeconds)) {
            return 'late';
        }
        
        return 'normal';
    }
    
    /**
     * 计算最终状态
     */
    private function calculateFinalStatus($currentStatus, $clockOutTime) {
        if ($currentStatus === 'late') {
            return $currentStatus;
        }
        
        $workEndTime = $this->getConfig('work_end_time', '18:30:00');
        $earlyLeaveThreshold = $this->getConfig('early_leave_threshold', 15);
        
        $clockOutTimestamp = strtotime($clockOutTime);
        $workEndTimestamp = strtotime($workEndTime);
        $earlyThresholdSeconds = $earlyLeaveThreshold * 60;
        
        if ($clockOutTimestamp < ($workEndTimestamp - $earlyThresholdSeconds)) {
            return 'early_leave';
        }
        
        return 'normal';
    }
    
    /**
     * 获取用户月度考勤报告
     */
    public function getMonthlyReport($userId, $year, $month) {
        $startDate = date('Y-m-01', strtotime("$year-$month-01"));
        $endDate = date('Y-m-t', strtotime("$year-$month-01"));
        
        $sql = "SELECT * FROM attendance_records 
                WHERE user_id = ? AND record_date BETWEEN ? AND ? 
                ORDER BY record_date";
        
        $records = $this->db->query($sql, [$userId, $startDate, $endDate]);
        
        // 统计信息
        $stats = [
            'total_days' => 0,
            'work_days' => 0,
            'normal_days' => 0,
            'late_days' => 0,
            'early_leave_days' => 0,
            'absent_days' => 0,
            'total_hours' => 0,
            'avg_hours' => 0
        ];
        
        foreach ($records as $record) {
            $stats['total_days']++;
            
            // 判断是否有打卡记录（上午或下午）
            $hasClockIn = $record['morning_clock_in'] || $record['afternoon_clock_in'];
            
            if ($hasClockIn) {
                $stats['work_days']++;
                $stats['total_hours'] += $record['total_work_hours'] ?? 0;
                
                switch ($record['status']) {
                    case 'normal':
                        $stats['normal_days']++;
                        break;
                    case 'late':
                        $stats['late_days']++;
                        break;
                    case 'early_leave':
                        $stats['early_leave_days']++;
                        break;
                }
            } else {
                $stats['absent_days']++;
            }
        }
        
        if ($stats['work_days'] > 0) {
            $stats['avg_hours'] = round($stats['total_hours'] / $stats['work_days'], 2);
        }
        
        return [
            'records' => $records,
            'stats' => $stats,
            'month' => $month,
            'year' => $year
        ];
    }
    
    /**
     * 获取系统配置
     */
    private function getConfig($key, $default = '') {
        $sql = "SELECT config_value FROM system_config WHERE config_key = ?";
        $result = $this->db->querySingle($sql, [$key]);
        return $result ? $result['config_value'] : $default;
    }
    
    /**
     * 获取用户考勤记录
     */
    public function getUserRecords($userId, $startDate, $endDate, $limit = 50) {
        $sql = "SELECT ar.*, u.full_name, u.department 
                FROM attendance_records ar 
                JOIN users u ON ar.user_id = u.id 
                WHERE ar.user_id = ? AND ar.record_date BETWEEN ? AND ? 
                ORDER BY ar.record_date DESC 
                LIMIT ?";
        
        return $this->db->query($sql, [$userId, $startDate, $endDate, $limit]);
    }
    
    /**
     * 获取所有用户考勤记录（管理员用）
     */
    public function getAllRecords($startDate, $endDate, $department = '', $limit = 100) {
        $sql = "SELECT ar.*, u.full_name, u.department, u.position 
                FROM attendance_records ar 
                JOIN users u ON ar.user_id = u.id 
                WHERE ar.record_date BETWEEN ? AND ?";
        
        $params = [$startDate, $endDate];
        
        if (!empty($department)) {
            $sql .= " AND u.department = ?";
            $params[] = $department;
        }
        
        $sql .= " ORDER BY ar.record_date DESC, u.department, u.full_name LIMIT ?";
        $params[] = $limit;
        
        return $this->db->query($sql, $params);
    }
    
    /**
     * 手动添加考勤记录
     */
    public function addManualRecord($recordData) {
        // 验证必填字段
        $required = ['user_id', 'record_date'];
        foreach ($required as $field) {
            if (empty($recordData[$field])) {
                return ['success' => false, 'message' => "{$field} 不能为空"];
            }
        }
        
        // 检查记录是否已存在
        $existing = $this->db->querySingle(
            "SELECT id FROM attendance_records WHERE user_id = ? AND record_date = ?",
            [$recordData['user_id'], $recordData['record_date']]
        );
        
        if ($existing) {
            return ['success' => false, 'message' => '该日期的考勤记录已存在'];
        }
        
        // 计算工作时长和状态
        $totalHours = 0;
        $status = $recordData['status'] ?? 'normal';
        
        // 计算上午工时
        if (!empty($recordData['morning_clock_in']) && !empty($recordData['morning_clock_out'])) {
            $morningHours = $this->calculateWorkHours($recordData['morning_clock_in'], $recordData['morning_clock_out']);
            $totalHours += $morningHours;
        }
        
        // 计算下午工时
        if (!empty($recordData['afternoon_clock_in']) && !empty($recordData['afternoon_clock_out'])) {
            $afternoonHours = $this->calculateWorkHours($recordData['afternoon_clock_in'], $recordData['afternoon_clock_out']);
            $totalHours += $afternoonHours;
        }
        
        // 出差状态使用全天工时
        if ($status === 'business_trip' && !empty($recordData['all_day_work_hours'])) {
            $totalHours = $recordData['all_day_work_hours'];
        }
        
        $sql = "INSERT INTO attendance_records (user_id, record_date, morning_clock_in, morning_clock_out, afternoon_clock_in, afternoon_clock_out, all_day_work_hours, total_work_hours, status, notes) 
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        
        $params = [
            $recordData['user_id'],
            $recordData['record_date'],
            $recordData['morning_clock_in'] ?? null,
            $recordData['morning_clock_out'] ?? null,
            $recordData['afternoon_clock_in'] ?? null,
            $recordData['afternoon_clock_out'] ?? null,
            $recordData['all_day_work_hours'] ?? null,
            $totalHours,
            $status,
            $recordData['notes'] ?? ''
        ];
        
        try {
            $this->db->execute($sql, $params);
            return ['success' => true, 'message' => '考勤记录添加成功'];
        } catch (Exception $e) {
            return ['success' => false, 'message' => '添加失败: ' . $e->getMessage()];
        }
    }
    
    /**
     * 计算手动添加记录的状态
     */
    private function calculateManualStatus($clockIn, $clockOut) {
        $clockInStatus = $this->calculateClockInStatus($clockIn);
        $finalStatus = $this->calculateFinalStatus($clockInStatus, $clockOut);
        return $finalStatus;
    }
}

// 创建全局考勤实例
function getAttendance() {
    static $attendance = null;
    if ($attendance === null) {
        $attendance = new Attendance();
    }
    return $attendance;
}
?>
